package git

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

type GitRepo struct {
	Repo_dir string
}

func (this *GitRepo) switch_dir(wrapper func(s string) string) func(s string) string {
	return func(s string) string {
		curr_dir, _ := os.Getwd()
		os.Chdir(this.Repo_dir)
		str_ret := wrapper(s)
		os.Chdir(curr_dir)
		return str_ret
	}
}

func (this *GitRepo) Status(type_ string) []string {
	curr_dir, _ := os.Getwd()
	os.Chdir(this.Repo_dir)
	out, _ := exec.Command("git", "status", "-s").Output()
	os.Chdir(curr_dir)

	list_lines := strings.Split(string(out), "\n")
	if type_ == "*" {
		return list_lines
	}
	// else

	var list_filter []string
	for _, line := range list_lines {
		if line == "" {
			continue
		}
		state_mixed := line[:2]
		path_file := line[3:]

		map_checking := map[string]bool{
			"untracked":        state_mixed == "??",
			"added":            state_mixed[0] != ' ',
			"unadded":          state_mixed[1] != ' ',
			"new_added":        state_mixed[0] == 'A',
			"new_unadded":      state_mixed[1] == 'A',
			"modified_added":   state_mixed[0] == 'M',
			"modified_unadded": state_mixed[1] == 'M',
			"deleted_added":    state_mixed[0] == 'D',
			"deleted_unadded":  state_mixed[1] == 'D',
		}
		if checked, ok := map_checking[type_]; ok {
			if checked {
				list_filter = append(list_filter, path_file)
			}
		} else {
			panic("不支持的filter格式：" + type_)
		}
	}
	return list_filter
}

func (this *GitRepo) Add_one(relpath_item string) bool {
	ret := true
	curr_dir, _ := os.Getwd()
	os.Chdir(this.Repo_dir)
	err := exec.Command("git", "add", relpath_item).Run()
	if err != nil {
		panic(fmt.Sprintf("'git add %v' 操作失败", relpath_item))
		ret = false
	}
	os.Chdir(curr_dir)
	return ret
}

func (this *GitRepo) Add(items []string) bool {
	ret := true
	curr_dir, _ := os.Getwd()
	os.Chdir(this.Repo_dir)

	for _, relpath_item := range items {
		err := exec.Command("git", "add", relpath_item).Run()
		if err != nil {
			panic(fmt.Sprintf("'git add %v' 操作失败", relpath_item))
			ret = false
		}
	}
	os.Chdir(curr_dir)
	return ret
}

func (this *GitRepo) Commit(message string) bool {
	ret := true
	curr_dir, _ := os.Getwd()
	os.Chdir(this.Repo_dir)
	err := exec.Command("git", "commit", "-m", "\""+message+"\"").Run()
	if err != nil {
		panic("'git commit -m ...' 操作失败")
		ret = false
	}
	os.Chdir(curr_dir)
	return ret
}
